PrivateリポジトリのActionsWorkflow内Stepを共有するためCompositeRunStepを外部参照無しに同リポジトリ内で完結させてみた
GitHub Actionsで複数Workflowを追加していくと、Workflow間でStepが重複している事はよくあります。重複部分を共有化できる機能としてcomposite run stepsも既にリリースされていますが、正直色々ちょっとわかりにくい。原因としては以下あたり。
- 今使っているリポジトリで有効か分からない
- 使えるとしてどう使えばいいのかわからない
最初にこの機能を知ったときには「共有化したStepをパブリックにすること前提」という一文を見かけて「あ、オープンソースじゃないと使えないな」と判断したのですが、最近幾つか検索して見当たった事例をみると同一リポジトリ内に設置できることを知り、実際にやってみました。
Composite Run Stepを使える条件
GitHub Actionsが使えるなら使えます。Actionsが使える条件は新プランであること(プライベートリポジトリ作成数無制限)。指定が若干異なってきますが、リポジトリがプライベート・パブリックのいずれもOK。
同一リポジトリで構成する
同一リポジトリ内で管理したい場合は以下の構成に従います。Composite Run StepはWorkflowとは別ディレクトリ管理になります。
Type | Path |
---|---|
Workflow | .github/workflow/TEMPLATE.yml |
CompositeRunStep | .github/actions/TEMPLATE/action.yml |
TEMPLATE
の箇所がユーザ定義となります。Workflowの場合はファイル名が、CompositeRunStepの場合はディレクトリ名で見分けをつける形です。
テンプレートファイルの書き方
これもPublicリポジトリと変わりません。内容については公式ドキュメントのサンプルを挙げてみます。
name: 'Hello World' description: 'Greet someone' inputs: who-to-greet: # id of input description: 'Who to greet' required: true default: 'World' outputs: random-number: description: "Random number" value: ${{ steps.random-number-generator.outputs.random-id }} runs: using: "composite" steps: - run: echo Hello ${{ inputs.who-to-greet }}. shell: bash - id: random-number-generator run: echo "::set-output name=random-id::$(echo $RANDOM)" shell: bash - run: ${{ github.action_path }}/goodbye.sh shell: bash
runs:steps:以降にWorkflowの重複Stepを持ってきます。他のActionをuse不可能なことだけ注意が必要です。複数のStepを纏めてCompositeに持ってきたい場合は事前に順番を整理しておくとよいでしょう。
inputはActionを利用する際のWithが該当し、outputsはActionで生成された値を用いる場合に使う${{ steps.foo.outputs.random-number }}
の指定用です。
制約はあるものの、重複部分を抽出したテンプレートの書き方はとてもシンプルです。
実際にWorkflowで使う場合
ポイントは呼び出し方。Workflowの一部を抜粋したものを例にします。env:ENVIRONMENT:の指定でわかるように、環境別でWorkflowを替えているケースです。ここからCompositeの対処を入れてみます。
name: "Develop: Deploy Redash" on: [workflow_dispatch] env: ENVIRONMENT: develop defaults: run: working-directory: tools/redash jobs: deploy: name: Deploy runs-on: ubuntu-18.04 steps: - name: Set up Node uses: actions/setup-node@v1 with: node-version: '10.x' - uses: actions/setup-python@v2 with: python-version: '3.7' - name: Checkout uses: actions/checkout@v2 - name: Install System Dependencies run: | sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libcurl4-openssl-dev
外部Actionを使っていないのはInstall System Dependencies
のStepだけですが、インストールするライブラリをWorkflow毎に管理するのはトラブルの原因なのでまとめることにします。
公式ドキュメントのサンプルをベースにしつつ、今回不要なもの(inputs, outputs)は外します。
% vim .github/actions/install_dependecies/action.yml
name: 'Install System Dependencies' description: 'dependencies install step' runs: using: "composite" steps: - run: | sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libcurl4-openssl-dev shell: bash
次にこれをWorkflowから呼び出します。
name: "Develop: Deploy Redash" on: [workflow_dispatch] env: ENVIRONMENT: develop defaults: run: working-directory: tools/redash jobs: deploy: name: Deploy runs-on: ubuntu-18.04 steps: - name: Set up Node uses: actions/setup-node@v1 with: node-version: '10.x' - uses: actions/setup-python@v2 with: python-version: '3.7' - name: Checkout uses: actions/checkout@v2 - name: Install System Dependencies uses: ./.github/actions/install_dependecies
指定する際のポイントとしては、
- actions/checkoutにてソースコードをチェックアウトしておく
- ワークスペースからの相対指定が必要(NG: .github, OK: ./.github)
1についてはチェックアウトしないと共通化したテンプレートが見つからないためです。2は相対指定にしなかった場合外部リポジトリを探そうとします。
The workflow is not valid. .github/workflows/deploy.yml (Line: 16, Col: 15): Expected format {org}/{repo}[/path]@ref. Actual '.github/actions/hello_world' Input string was not in a correct format.
あとがき
一度理解するとWorkflowの整理に俄然乗り出したくなりますが、Composite内でActionは利用不可です。また、外部Actionを自作してComposite化する手もありますが、その分メンテナンスの負担が増します。無理なくそつない感じで使ってみましょう。